﻿module Preprocessor.Include

open Preprocessor.Prep
open Lexer
open System.IO

let findFile (context:Context) (prep:Prep) isNext (str:string) = 
    if isNext then 
       let startInd = match ResizeArray.tryFindIndex (fun x -> x= Path.GetDirectoryName(prep.FullSourceFilename)) context.SearchDirs with 
                      |Some i-> i | None -> 0
       let files = seq { for i in [startInd..(ResizeArray.length context.SearchDirs)-1] do
                             yield! Directory.EnumerateFiles(context.SearchDirs.[i], str.Substring(1, str.Length-2), SearchOption.TopDirectoryOnly) 
                       }
       if Seq.isEmpty files then failwith "Can't find include " + str 
       else Seq.head files
    else 
        if (str.[0]='\"' && str.[str.Length - 1]='\"') then 
            let files = seq { yield! Directory.EnumerateFiles(Path.GetDirectoryName (prep.FullSourceFilename), str.Substring(1, str.Length-2), SearchOption.TopDirectoryOnly)
                              for dir in context.SearchDirs do
                                yield! Directory.EnumerateFiles( dir, str.Substring(1, str.Length-2), SearchOption.TopDirectoryOnly) 
                            }
            if Seq.isEmpty files then failwith "Can't find include" 
            else Seq.head files
        elif (str.[0]='<' && str.[str.Length - 1]='>') then
            let files = seq { for dir in context.SearchDirs do
                                yield! Directory.EnumerateFiles( dir, str.Substring(1, str.Length-2), SearchOption.AllDirectories)
                            }
            if Seq.isEmpty files then failwith "Can't find include"
            else Seq.head files
        else
            failwith "Not implemented include"

let lexicInclude (context:Context) (prep:Prep) str = 
    str |> findFile context prep false


let lexicIncludeNext (context:Context) (prep:Prep) str = 
    str |> findFile context prep true
